/**
 * 
 */
package com.chee.plant.encrypt;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;

/**
 * 
 */
public class Des {
	private String _rawKey;
	private SecureRandom _secRand;
	private SecretKey _key;
	private Cipher _cipher;

	/*
	 * constructor
	 */
	public Des(String rawKey) {
		this.set_rawKey(rawKey);
	}
	public String decryptString(String rawString){
		byte[] rawData = hex2byte(rawString.getBytes());
		byte[] decData = this.decrypt(rawData);
		return new String(decData);
	}
	public byte[] decrypt(byte[] rawData) {
		if (rawData == null || rawData.length==0) return new byte[0];
		try {
			this._cipher.init(Cipher.DECRYPT_MODE, this._key, this._secRand);
			byte[] decryptedData = this._cipher.doFinal(rawData);
			return decryptedData;
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new byte[0];
	}
	public String encryptString(String rawString){
		String _rawString = rawString;
//		if(_rawString.length() % 8 != 0){
//			int count = 8 - _rawString.length() % 8;
//			for(int i=0; i<count; i++) _rawString += " ";
//		}
		byte[] rawData = _rawString.getBytes();
		byte[] encData = this.encrypt(rawData);
		return byte2hex(encData);
	}
	public byte[] encrypt(byte[] rawData) {
		if (rawData == null || rawData.length==0) return new byte[0];
		try {
			this._cipher.init(Cipher.ENCRYPT_MODE, this._key, this._secRand);
			byte[] encryptedData = this._cipher.doFinal(rawData);
			return encryptedData;
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new byte[0];
	}

	public void set_rawKey(String _key) {
		this._rawKey = _key;
		byte[] rawKeyByte = this._rawKey.getBytes();
		this._secRand = new SecureRandom();
		try {
			DESKeySpec dks = new DESKeySpec(rawKeyByte);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
			SecretKey key = factory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance("DES");
			this._key = key;
			this._cipher = cipher;
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String get_rawKey() {
		return _rawKey;
	}
	public String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) hs = hs + "0" + stmp;
			else hs = hs + stmp;
		}
		return hs.toUpperCase();
	}
	public byte[] hex2byte(byte[] b) {
		if ((b.length % 2) != 0)
			throw new IllegalArgumentException("");
		byte[] b2 = new byte[b.length / 2];
		for (int n = 0; n < b.length; n += 2) {
			String item = new String(b, n, 2);
			b2[n / 2] = (byte) Integer.parseInt(item, 16);
		}
		return b2;
	}
	public static void main(String[] args){
		String key = "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest";
		Des des = new Des(key);
		String raw = "new string is ok?";
		System.out.println(raw);
		String en = des.encryptString(raw);
		System.out.println(en);
		String de = des.decryptString(en);
		System.out.println(de);
	}
}
